package com.jz.cash.client.service.impl;

import com.jz.cash.client.entity.CountCharteredConfig;
import com.jz.cash.client.entity.TableConfig;
import com.jz.cash.client.entity.TableRecord;
import com.jz.cash.client.entity.TableType;
import com.jz.cash.client.exception.CustomException;
import com.jz.cash.client.model.User;
import com.jz.cash.client.query.PageBean;
import com.jz.cash.client.query.QueryBean;
import com.jz.cash.client.query.QueryBeanParsing;
import com.jz.cash.client.service.*;
import com.jz.cash.client.states.CountRoleState;
import com.jz.cash.client.states.DeleteState;
import com.jz.cash.client.states.TableState;
import com.jz.cash.client.utils.DateTimeUtils;
import com.jz.cash.client.vo.OpenStageVo;
import com.jz.cash.client.vo.ReserveTableVo;
import com.jz.cash.client.vo.TableConfigVo;
import com.jz.cash.client.vo.TableInfoVo;
import com.stip.mybatis.generator.plugin.BaseExample;
import com.stip.mybatis.generator.plugin.BaseService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.jz.cash.client.states.CountRoleState.*;
import static com.jz.cash.client.states.CountRoleState.CHARTERED;

@Service
public class TableConfigServiceImpl extends BaseService<TableConfig, BaseExample, Long> implements TableConfigService {

    @Autowired
    private TableRecordService tableRecordService;

    @Autowired
    private TableTypeService tableTypeService;

    //按小时计费
    @Autowired
    private CountHourConfigService countHourConfigService;

    //分时段计费
    @Autowired
    private CountHourintervalConfigService countHourintervalConfigService;

    //包场计费
    @Autowired
    private CountCharteredConfigService countCharteredConfigService;


    @Override
    public PageBean<TableConfigVo> list(QueryBean queryBean) {

        //解析queryBean成Example
        BaseExample example = QueryBeanParsing.convertQueryBeanToBaseExample(queryBean);

        int total = countByExample(example);

        PageBean pageBean = PageBean.init(total,queryBean.getPage(),queryBean.getSize());

        example.setFromRowNum(pageBean.getCurrentPage());
        example.setToRowNum(pageBean.getPageSize());

        List<TableConfig> tableConfigs = selectByExample(example);




        List<TableConfigVo> resp = new ArrayList<>();
        if (!CollectionUtils.isEmpty(tableConfigs)) {
            resp = tableConfigs.stream().map(f -> {
                TableConfigVo vo = new TableConfigVo();
                BeanUtils.copyProperties(f, vo);
                return vo;
            }).collect(Collectors.toList());
        }

        pageBean.setItems(resp);
        return pageBean;
    }

    @Override
    @Transactional
    public void reserveTable(ReserveTableVo reserve, User user) {
        TableConfig tableConfig = selectByPrimaryKey(reserve.getTableId());
        if (null == tableConfig) {
            throw new CustomException("桌台不存在");
        }
        if (null != tableConfig.getState() && TableState.IDLE.getCode() != tableConfig.getState().intValue()) {
            throw new CustomException("桌台已预定或开台");
        }

        tableConfig.setState(TableState.RESERVE.getCode());
        tableConfig.setLastModifier(user.getId());
        tableConfig.setLastModifyDate(new Date());
        tableConfig.setMerchantId(user.getMerchantId());
        updateByPrimaryKeySelective(tableConfig);

        TableRecord record = new TableRecord();

        record.setCreator(user.getId());
        record.setCreatedDate(tableConfig.getLastModifyDate());
        record.setMarkForDelete(DeleteState.TRUE.getState());
        record.setState(TableState.RESERVE.getCode());
        record.setRemark(reserve.getRemark());
        record.setTableId(tableConfig.getId());
        record.setCustomPhone(reserve.getCustomPhone());
        record.setCustomCount(reserve.getCustom());
        record.setOperated("桌台预定");
        tableRecordService.insertSelective(record);

    }

    @Override
    public void cancelReserve(Long tableId, User user) {

        TableConfig tableConfig = selectByPrimaryKey(tableId);
        if (null == tableConfig) {
            throw new CustomException("桌台不存在");
        }
        if (null != tableConfig.getState() && TableState.RESERVE.getCode() != tableConfig.getState().intValue()) {
            throw new CustomException("桌台不处于预定状态");
        }

        tableConfig.setState(TableState.IDLE.getCode());
        tableConfig.setLastModifyDate(new Date());
        tableConfig.setLastModifier(user.getId());

        updateByPrimaryKeySelective(tableConfig);

        TableRecord record = new TableRecord();

        record.setCreator(user.getId());
        record.setCreatedDate(tableConfig.getLastModifyDate());
        record.setMarkForDelete(DeleteState.TRUE.getState());
        record.setState(TableState.IDLE.getCode());
        record.setTableId(tableConfig.getId());
        record.setOperated("取消预定");
        tableRecordService.insertSelective(record);


    }

    @Override
    public void openStage(OpenStageVo open, User user) {
        TableConfig tableConfig = selectByPrimaryKey(open.getTableId());
        if (null == tableConfig) {
            throw new CustomException("桌台不存在");
        }
        if (null != tableConfig.getState() && TableState.OCCUPY.getCode() == tableConfig.getState().intValue()) {
            throw new CustomException("桌台已开台");
        }

        tableConfig.setState(TableState.OCCUPY.getCode());
        tableConfig.setLastModifier(user.getId());
        tableConfig.setLastModifyDate(new Date());

        updateByPrimaryKeySelective(tableConfig);

        TableRecord record = new TableRecord();

        record.setCreator(user.getId());
        record.setCreatedDate(tableConfig.getLastModifyDate());
        record.setMarkForDelete(DeleteState.TRUE.getState());
        record.setState(TableState.OCCUPY.getCode());
        record.setTableId(tableConfig.getId());
        record.setOperated("开台");
        record.setCountRoleId(open.getCountRoleId());
        record.setOpenStageDate(tableConfig.getLastModifyDate());
        record.setOpenStageEmployeeId(user.getId());
        record.setRemark(open.getRemark());
        record.setCustomCount(open.getCustomCount());
        tableRecordService.insertSelective(record);


    }

    @Override
    public TableInfoVo tableInfo(QueryBean queryBean) {
        TableInfoVo resp = new TableInfoVo();

        BaseExample example = QueryBeanParsing.convertQueryBeanToBaseExample(queryBean);
        List<TableConfig> tableConfigs = selectByExample(example);
        if (!CollectionUtils.isEmpty(tableConfigs)) {
            TableConfig tableConfig = tableConfigs.get(0);
            TableRecord record = tableRecordService.findLatestRecord(tableConfig.getId());
            if (null != record) {
                resp.setOpenStageTime(DateTimeUtils.formatDateTime(record.getOpenStageDate()));
                resp.setCountRoleId(record.getCountRoleId());
                resp.setTableNo(tableConfig.getTableNo());
                resp.setServiceCharge(getServiceChargeByCountRole(record.getOpenStageDate(),record.getCountRoleId(),queryBean.getCurrentUser()).doubleValue());
            }
            TableType tableType = tableTypeService.selectByPrimaryKey(tableConfig.getTableTypeId());
            if (null != tableType) {
                resp.setCategory(tableType.getName());
            }
        }
        return resp;
    }


    private BigDecimal getServiceChargeByCountRole(Date openStageDate,Long countRoleId,User user) {

        Date now = new Date();


        switch (getValue(countRoleId.intValue())) {
            case CHARTERED:
                return getServiceChargeByChartered(openStageDate,user.getMerchantId());
            case HOUR:
                return getServiceChargeByHour(openStageDate,user.getMerchantId());
            case HOUR_INTERVAL:
                return getServiceChargeByHourinterval(openStageDate,user.getMerchantId());
        }
        return BigDecimal.ZERO;
    }

    private BigDecimal getServiceChargeByHourinterval(Date openStateDate,long merchantId) {
        return null;
    }

    private BigDecimal getServiceChargeByHour(Date openStateDate,Long merchantId) {
        return null;
    }

    private BigDecimal getServiceChargeByChartered(Date openStageDate,Long merchantId) {
        CountCharteredConfig config = countCharteredConfigService.getRoleByMerchantId(merchantId);

        if (null != config.getServiceChargeCountType() && 0 != config.getServiceChargeCountType().intValue()) {
            //根据type获取不同的时间刻度。
            boolean halfHour = config.getServiceChargeCountType().intValue() == 1;
            long hourOfTwo = DateTimeUtils.getDistanceHourOfTwo(openStageDate, new Date(), halfHour);


        }

        return BigDecimal.ZERO;
    }
}